package twoD.IsoPfem;

import inf.v3d.view.Viewer;

import java.util.ArrayList;

import twoD.IsoPfem.math.FunctionRToR;
import twoD.IsoPfem.math.Interval;
import twoD.IsoPfem.utils.MeshUtilities;
import twoD.IsoPfem.utils.NodeUtilities;

public class SlabSpecimenDemo {

	/**
	 * use this mesh for element validation
	 * 
	 * @return
	 */
	public ElasticStructure createModel1() {
		Mesh M = MeshLibrary.createMesh1();
		ElasticStructure struct = new ElasticStructure(M);

		RealTable realTable = new RealTable(2e7, 0.3);
		realTable.setThickness(0.1);

		for (IGeometry g : M.getGeometries()) {
			struct.addElement(new CST(realTable, g));
		}
		// struct.setCType(CType.PLANE_STRAIN);
		return struct;
	}

	/**
	 * slab specimen model based on manually generated mesh
	 */
	private double[][] geomData = { { 22, 22, 2, 2, 6 }, { 6, 6, 2, 2, 2 },
			{ 62, 22, 2, 2, 6 } };

	public ElasticStructure createModel2() {

		double[] data = geomData[0];

		double l = data[0];
		double h = data[1];
		double t = data[2];
		double dt = data[3];
		double c = data[4];

		Mesh M = MeshLibrary.createMesh2(l, h, t, dt, c);

		ElasticStructure struct = new ElasticStructure(M);

		RealTable realTable = new RealTable(206900, 0.29);
		realTable.setThickness(0.1);

		for (IGeometry g : M.getGeometries()) {
			struct.addElement(new CST(realTable, g));
		}

		Constraint c1 = new Constraint(false, false);
		Constraint c2 = new Constraint(true, false);

		NodeUtilities.findNode(struct, 0.0, 0.0).get(0).setConstraint(c1);
		NodeUtilities.findNode(struct, l, 0.0).get(0).setConstraint(c2);

		Node n1 = NodeUtilities.findNode(struct, (l - t) / 2, h).get(0);
		Node n2 = NodeUtilities.findNode(struct, (l - t) / 2 + t, h).get(0);

		EdgeLoad el = new EdgeLoad(n1, n2, new FunctionRToR() {

			@Override
			public double valueAt(double x) {
				return -10;
			}

			@Override
			public int getP() {
				return 0;
			}

			@Override
			public Interval getDomain() {
				return new Interval(0, 1);
			}

			@Override
			public double[] getBreakpoints() {
				return null;
			}

			@Override
			public double derivativeAt(double x) {
				return 0;
			}
		});

		struct.enumerateDOFs();
		// in order to find elements, we have to enumerate first
		ArrayList<Integer> tmp = MeshUtilities.findElement(struct, n1, n2);
		for (int i : tmp)
			struct.getElements(i).addEdgeLoad(el);

		return struct;
	}

	/**
	 * model based on GiD data
	 * 
	 * @param args
	 */
	public ElasticStructure createModel3(int option) {
		Mesh M = MeshLibrary
				.createTriangleMeshFromGiD2("D:/Giang/vgu/zWork/simple_beam.gid/mesh3.txt");

		ElasticStructure struct = new ElasticStructure(M);

		RealTable realTable = new RealTable(50e9, 0.2);
		realTable.setThickness(1);

		if (option == 1) {
			for (IEdge e : M.getEdges())
				e.setMode(0);
			for (IFace f : M.getFaces())
				// doesn't need but want to make it as a prototype
				f.setMode(0);
			for (IGeometry g : M.getGeometries()) {
				struct.addElement(new CST(realTable, g));
			}
		} else if (option == 2) {
			for (IEdge e : M.getEdges())
				e.setMode(1);
			for (IFace f : M.getFaces())
				// doesn't need but want to make it as a prototype
				f.setMode(0);
			for (IGeometry g : M.getGeometries()) {
				struct.addElement(new CST2(realTable, g));
			}
		}

		Constraint c1 = new Constraint(false, false);
		Constraint c2 = new Constraint(true, false);

		NodeUtilities.findNode(struct, 0.0, 0.0).get(0).setConstraint(c1);
		NodeUtilities.findNode(struct, 100.0, 0.0).get(0).setConstraint(c2);

		Force f = new Force(0, -1e2);
		NodeUtilities.findNode(struct, 50.0, 40.0).get(0).setForce(f);

		return struct;
	}

	public static void main(String[] args) {
		ElasticStructure struct = new SlabSpecimenDemo().createModel1();

		struct.solveLinearStaticEquilibrium();
		struct.listingDisplacements();
		
		Viewer view = new Viewer();
		Visualizer viz = new Visualizer(struct, view);
		double d_max = viz.automaticScale();
		viz.drawConstraints();
		viz.drawForces();
		viz.drawEdgeLoads();
		viz.drawElements();

		viz.postAutomaticScale(d_max);
		// viz.drawDisplacedStructure();
		// viz.drawSigma11();
		//
		view.setVisible(true);
	}

}
